package ws

import (
	"gitee.com/lipore/go-nio/pkg/transport"
	"github.com/gorilla/websocket"
	"reflect"
)

type wsTransport struct {
	id    int64
	conn  *websocket.Conn
	ready bool
}

func newWsTransport(id int64, conn *websocket.Conn) transport.Transport {
	return &wsTransport{
		id:   id,
		conn: conn,
	}
}

func (w *wsTransport) Ready() {
	w.ready = true
}

func (w *wsTransport) Read(p []byte) (n int, err error) {
	if !w.ready {
		return 0, nil
	}
	_, nr, err := w.conn.NextReader()
	if err != nil {
		return 0, err
	}
	w.ready = false
	return nr.Read(p)
}

func (w *wsTransport) Write(p []byte) (n int, err error) {
	wr, err := w.conn.NextWriter(websocket.BinaryMessage)
	if err != nil {
		return 0, err
	}
	n, err = wr.Write(p)
	if err != nil {
		return 0, err
	}
	return n, wr.Close()
}

func (w *wsTransport) Close() error {
	return w.conn.Close()
}

func (w *wsTransport) FD() int {
	v := reflect.ValueOf(w.conn)
	conn := reflect.Indirect(v).FieldByName("conn").Elem()
	netFD := reflect.Indirect(conn).FieldByName("fd")
	pfd := reflect.Indirect(netFD).FieldByName("pfd")
	fd := int(reflect.Indirect(pfd).FieldByName("Sysfd").Int())
	return fd
}

func (w *wsTransport) ID() int64 {
	return w.id
}
